import xml.etree.ElementTree as ET
from collections import deque

def parse_xml_tree(xml_file):
    # 解析XML文件
    tree = ET.parse(xml_file)
    root = tree.getroot()
    
    # 初始化存储层次信息的字典
    hierarchy = {root: []}
    # 使用队列进行BFS遍历
    queue = deque([(root, 0)])  # (元素, 深度)
    elements_by_depth = {}      # 按深度存储元素
    
    while queue:
        element, depth = queue.popleft()
        
        # 记录当前深度的元素
        if depth not in elements_by_depth:
            elements_by_depth[depth] = []
        elements_by_depth[depth].append(element)
        
        # 准备处理子元素
        children = list(element)
        hierarchy[element] = children
        
        for child in children:
            queue.append((child, depth + 1))
    
    return root, hierarchy, elements_by_depth

def print_xml_hierarchy(root, hierarchy, elements_by_depth, output_file=None):
    """打印XML层级结构到控制台和/或文件
    
    Args:
        root: XML根元素
        hierarchy: 层级关系字典
        elements_by_depth: 按深度分组的元素
        output_file: 输出文件路径（可选）
    """
    # 如果指定了输出文件，则打开文件
    file_handle = None
    if output_file:
        try:
            file_handle = open(output_file, 'w', encoding='utf-8')
        except Exception as e:
            print(f"无法打开输出文件: {e}")
            file_handle = None
    
    # 辅助函数：输出到控制台和文件
    def write_output(text, end='\n'):
        """同时输出到控制台和文件（如果文件已打开）"""
        print(text, end=end)
        if file_handle:
            file_handle.write(text + end)
    
    # 打印根元素信息
    write_output(f"XML根元素: {root.tag}\n")
    
    # 打印分层元素统计
    write_output("元素层级统计:")
    for depth, elements in sorted(elements_by_depth.items()):
        write_output(f"层级 {depth}: {len(elements)} 个元素")
    
    # 打印树形结构
    write_output("\nXML树状结构:")
    stack = [(root, 0)]  # (元素, 深度)
    
    while stack:
        element, depth = stack.pop()
        
        # 处理元素标签（移除命名空间）
        tag = element.tag.split('}', 1)[-1] if '}' in element.tag else element.tag
        
        # 打印带缩进的元素标签和属性
        indent = "|   " * (depth - 1) + "|-- " if depth > 0 else ""
        attrs = "".join([f' {k}="{v}"' for k, v in element.attrib.items()])
        write_output(f"{indent}{tag}{attrs}")
        
        # 添加文本内容（如果有）
        if element.text and element.text.strip():
            text_indent = "|   " * depth + "|   "
            write_output(f"{text_indent}文本: '{element.text.strip()}'")
        
        # 逆向添加子元素以便保持原始顺序
        for child in reversed(hierarchy[element]):
            stack.append((child, depth + 1))
    
    # 关闭文件句柄
    if file_handle:
        file_handle.close()
        print(f"\nXML结构已保存到文件: {output_file}")

if __name__ == "__main__":
    xml_file = r"language_C\658.xml"  # 替换为你的XML文件路径
    output_file = "xml_structure.txt"  # 输出文件路径
    
    root, hierarchy, elements_by_depth = parse_xml_tree(xml_file)
    
    # 同时输出到控制台和文件
    print_xml_hierarchy(root, hierarchy, elements_by_depth, output_file)